package com.guldan.jaina.task;

import com.alibaba.fastjson.JSON;
import com.guldan.core.constants.CommonConstant;
import com.guldan.core.enums.ProjectRegisterBatchEn;
import com.guldan.core.enums.ProjectRegisterEn;
import com.guldan.core.enums.ValidatingRegisterTypeEn;
import com.guldan.core.utils.DateUtil;
import com.guldan.jaina.dto.citizeninfo.CitizenInfoDTO;
import com.guldan.jaina.dto.citizenproperty.CitizenPropertyDTO;
import com.guldan.jaina.dto.dictionary.DictionaryDTO;
import com.guldan.jaina.dto.progress.BarDTO;
import com.guldan.jaina.dto.projectextensiondetail.ProjectExtDataSampleDTO;
import com.guldan.jaina.dto.projectextensiondetail.ProjectExtensionDetailDTO;
import com.guldan.jaina.dto.projectextensiondetail.ProjectExtensionDetailSearchDTO;
import com.guldan.jaina.dto.projectextensiondic.ProjectExtensionDicDTO;
import com.guldan.jaina.dto.projectregisterbatch.CopyBatchDataDTO;
import com.guldan.jaina.dto.projectregisterupload.ProjectRegisterUploadDTO;
import com.guldan.jaina.dto.register.RegisterTemplateDataDTO;
import com.guldan.jaina.dto.registerfail.RegisterFailDTO;
import com.guldan.jaina.dto.registersuccess.RegisterSuccessDTO;
import com.guldan.jaina.dto.users.UsersDTO;
import com.guldan.jaina.manager.*;
import com.guldan.jaina.utils.UserUtils;
import com.guldan.jaina.utils.validating.CheckIdCard;
import com.guldan.mapper.db.entity.*;
import com.guldan.mapper.db.mapper.ProjectRegisterBatchMapperExt;
import com.guldan.mapper.db.mapper.RegisterSuccessMapperExt;
import net.sf.json.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * Created by Silas.
 * Date: 2017/1/11
 * Time: 15:19
 */
public class CopyBatchDataThread implements Runnable {

    public Logger logger = LoggerFactory.getLogger(getClass());

    private LinkedBlockingQueue<RegisterSuccess> queue;

    private BarDTO barDTO;

    private String threadName;

    private UsersDTO usersDTO;

    private Integer uploadId;

    private Integer destBatchId;

    private CopyBatchDataDTO copyBatchDataDTO;

    private ProjectExtensionDetailManager projectExtensionDetailManager;

    private RegisterSuccessMapperExt registerSuccessMapperExt;

    private ProjectRegisterBatchMapperExt projectRegisterBatchMapperExt;

    private RegisterFailManager registerFailManager;

    private ProjectRegisterUploadManager projectRegisterUploadManager;

    private CitizenPropertyManager citizenPropertyManager;

    public void setCitizenPropertyManager(CitizenPropertyManager citizenPropertyManager) {
        this.citizenPropertyManager = citizenPropertyManager;
    }

    public void setProjectRegisterUploadManager(ProjectRegisterUploadManager projectRegisterUploadManager) {
        this.projectRegisterUploadManager = projectRegisterUploadManager;
    }

    public void setRegisterSuccessMapperExt(RegisterSuccessMapperExt registerSuccessMapperExt) {
        this.registerSuccessMapperExt = registerSuccessMapperExt;
    }

    public void setProjectRegisterBatchMapperExt(ProjectRegisterBatchMapperExt projectRegisterBatchMapperExt) {
        this.projectRegisterBatchMapperExt = projectRegisterBatchMapperExt;
    }

    public void setRegisterFailManager(RegisterFailManager registerFailManager) {
        this.registerFailManager = registerFailManager;
    }

    public void setUploadId(Integer uploadId) {
        this.uploadId = uploadId;
    }

    public void setDestBatchId(Integer destBatchId) {
        this.destBatchId = destBatchId;
    }


    public void setProjectExtensionDetailManager(ProjectExtensionDetailManager projectExtensionDetailManager) {
        this.projectExtensionDetailManager = projectExtensionDetailManager;
    }

    public void setCopyBatchDataDTO(CopyBatchDataDTO copyBatchDataDTO) {
        this.copyBatchDataDTO = copyBatchDataDTO;
    }

    public void setQueue(LinkedBlockingQueue<RegisterSuccess> queue) {
        this.queue = queue;
    }

    public void setBarDTO(BarDTO barDTO) {
        this.barDTO = barDTO;
    }

    public void setUsersDTO(UsersDTO usersDTO) {
        this.usersDTO = usersDTO;
    }

    public void setThreadName(String threadName) {
        this.threadName = threadName;
    }

    @Override
    public void run() {

        UserUtils.setUser(this.usersDTO);
        logger.info(this.threadName + " begin");

        while (queue != null && queue.size() > 0) {
            RegisterSuccess dto = null;
            try {
                dto = queue.take();
                int oldRegisterId = dto.getRegisterId();
                Map<String, Object> map = validateAndUpdate(dto, this.destBatchId, this.uploadId);
                Integer validatingResult = (Integer) map.get("code");

                //deal project_extension_detail
                if (validatingResult.intValue() == ValidatingRegisterTypeEn.success.getCode().intValue()) {
//                successCount++;

                    //查询历史扩展属性字段值列表
                    ProjectExtensionDetailSearchDTO searchDTO = new ProjectExtensionDetailSearchDTO();
                    searchDTO.setRegisterId(oldRegisterId);
                    searchDTO.setBatchId(copyBatchDataDTO.getBatchId());
                    List<ProjectExtensionDetailDTO> projectExtensionDetailDTOs = projectExtensionDetailManager.list(searchDTO);

                    if (projectExtensionDetailDTOs != null && projectExtensionDetailDTOs.size() > 0) {

                        for (ProjectExtensionDetailDTO p : projectExtensionDetailDTOs) {

                            ProjectExtensionDetailDTO extDetailDto = new ProjectExtensionDetailDTO();
                            extDetailDto.setBatchId(dto.getBatchId());
                            extDetailDto.setExtContent(p.getExtContent());
                            extDetailDto.setExtId(p.getExtId());
                            extDetailDto.setExtName(p.getExtName());
                            extDetailDto.setProjectId(p.getProjectId());
                            extDetailDto.setYear(copyBatchDataDTO.getYear());
                            extDetailDto.setRegisterId((Integer) map.get("registerId"));
                            projectExtensionDetailManager.save(extDetailDto);
                        }
                    }
                    this.barDTO.finishAdd(true);

                } else {
                    //to do
//                failCount++;

                    this.barDTO.finishAdd(false);
                }


            } catch (Exception ex) {
                ex.printStackTrace();

                logger.error("QQQQQQQQQ+" + ex.getMessage() + "\n" + JSON.toJSONString(dto));
                barDTO.finishAdd(false);
            } finally {
                logger.info("barDTO SSSSS " + barDTO.toString());
                //判断是否已经上传导入完成
                if (barDTO.getOver()) {
                    //更新上传记录表
                    ProjectRegisterUploadDTO projectRegisterUploadDTO = projectRegisterUploadManager.get(this.uploadId);
                    projectRegisterUploadDTO.setSuccessNum(barDTO.getSuccess());
                    projectRegisterUploadDTO.setFailNum(barDTO.getFail());
                    projectRegisterUploadManager.save(projectRegisterUploadDTO);
                }
            }
        }

    }


    public Map<String, Object> validateAndUpdate(RegisterSuccess dto, Integer batchId, Integer uploadId) {

        Map<String, Object> map = new HashMap<String, Object>();


        //校验 已在%s区划中登记，%s批次中登记 begin
        //先校验是否是特殊人员，不是特殊人员才进行校验
        CitizenPropertyDTO citizenPropertyDTO = citizenPropertyManager.getByCitizenInfoId(dto.getCitizenInfoId());
        if (citizenPropertyDTO.getSpecial() == null || !citizenPropertyDTO.getSpecial()) {

            RegisterSuccessExample rsExample = new RegisterSuccessExample();
            RegisterSuccessExample.Criteria rsCriteria = rsExample.createCriteria();
            //rsCriteria.andAreaIdEqualTo(dto.getAreaId());   //项目登记区划
            rsCriteria.andYearEqualTo(dto.getYear());   //年度，
            rsCriteria.andProjectIdEqualTo(dto.getProjectId()); //项目id
            rsCriteria.andSubsidyCountEqualTo(dto.getSubsidyCount());  //发放次数
            rsCriteria.andIdentNumberEqualTo(dto.getIdentNumber());  //身份证号码
            rsCriteria.andStateNotEqualTo(ProjectRegisterEn.bank_fail.getCode());    //剔除发放失败状态，发放失败状态可以再继续登记
            rsCriteria.andIsDeleteEqualTo(false);    //过滤已经删除的
            List<RegisterSuccess> registerSuccessList = registerSuccessMapperExt.selectByExample(rsExample);

//        List<RegisterSuccessDTO> registerSuccessList = registerSuccessManager.getRegisterSuccessList(searchDTO);
            if (registerSuccessList != null && registerSuccessList.size() > 0) {
                //如果有，则取出，之前的登记批次信息，获取之前的登记区划信息
                ProjectRegisterBatch oldPrb = projectRegisterBatchMapperExt.selectByPrimaryKey(registerSuccessList.get(0).getBatchId());

                saveRegisterFail(dto, batchId, uploadId, String.format(ValidatingRegisterTypeEn.hasOwnedSubsidyBatch.getMean(), oldPrb.getAreaName(), dto.getYear() + "年第" + dto.getSubsidyCount() + "次"));
                map.put("code", ValidatingRegisterTypeEn.hasOwnedSubsidyBatch.getCode());
                return map;
            }
            //校验 已在%s区划中登记，%s批次中登记 end
        }
        //通过所有校验，写入登记成功表
        if (UserUtils.isTowns()) {
            dto.setState(ProjectRegisterEn.register_ing.getCode());
        } else
            dto.setState(ProjectRegisterEn.org_auditor_ing.getCode());
        RegisterSuccess entity = saveRegisterSuccess(dto);
        map.put("code", ValidatingRegisterTypeEn.success.getCode());
        map.put("registerId", entity.getRegisterId());

        return map;
    }

    /**
     * 写入失败表
     *
     * @param dto
     * @param uploadId
     */
    private RegisterFailDTO saveRegisterFail(RegisterSuccess dto
            , Integer batchId, Integer uploadId
            , String failReason) {

        RegisterFailDTO record = new RegisterFailDTO();

        record.setUploadId(uploadId);
        record.setBatchId(batchId);

        //record.setCitizenInfoId();
//        record.setProjectName(dto.getProjectName());
        record.setYear(dto.getYear());
        record.setSubsidyCount(dto.getSubsidyCount());
//        record.setRegisterAreaName(dto.getRegisterAreaName());
//        record.setAreaName(dto.getAreaName());
        record.setName(dto.getName());
        record.setIdentNumber(dto.getIdentNumber());
//        record.setBankName(dto.getBankName());
        record.setBankNumber(dto.getBankNumber());

//        record.setExtData(dto.getExtData());
        record.setFailReason(failReason);

        record.setSubsidyMoney("0");

        /*if (header != null) {
            BigDecimal[] values = dto.getValues();
            List<ProjectExtDataSampleDTO> pedList = new ArrayList<>();
            for (int i = 0; i < header.length; i++) {
                ProjectExtDataSampleDTO extDetailDto = new ProjectExtDataSampleDTO();
                String extName = header[i];

                //get extensions
                if (values[i] == null || values[i].compareTo(BigDecimal.ZERO) == 0)
                    extDetailDto.setExtContent("0");
                else
                    extDetailDto.setExtContent(new DecimalFormat("#.00").format(values[i]));
                extDetailDto.setExtId(extId[i]);
                extDetailDto.setExtName(extName);

                pedList.add(extDetailDto);
            }

            record.setExtData(JSONArray.fromObject(pedList).toString());
        }*/


        return registerFailManager.save(record);
    }

    private RegisterSuccess saveRegisterSuccess(RegisterSuccess entity) {

        /*
        RegisterSuccessDTO record = new RegisterSuccessDTO();
        record.setUploadId(uploadId);
        record.setBatchId(batchId);
        record.setProjectId(dto.getProjectId());
        record.setOrgCode(projectOrgCode);
        record.setPayCycleCode(projectPayCycleCode);
        record.setYear(dto.getYear());
        record.setName(dto.getName());
        record.setSubsidyCount(dto.getSubsidyCount());
        record.setBankCode(dto.getBankCode());
        record.setBankNumber(dto.getBankNumber());
        record.setSubsidyMoney(new BigDecimal(new DecimalFormat("#.00").format(dto.getMoney())));
        record.setState(ProjectRegisterBatchEn.register_ing.getCode());

        CitizenInfoDTO citizenInfo = citizenInfoManager.get(citizenInfoId);

        record.setAddress(citizenInfo.getAddress());
        record.setAddressZw(citizenInfo.getAddressZw());
        record.setAreaId(citizenInfo.getAreaId());
        record.setBirthday(citizenInfo.getBirthday());
        record.setCitizenInfoId(citizenInfo.getCitizenInfoId());
        record.setCitizenInfoTypeCode(citizenInfo.getCitizenInfoTypeCode());
        record.setDegreeCode(citizenInfo.getDegreeCode());
        record.setGenderCode(citizenInfo.getGenderCode());
        record.setHouseholdId(citizenInfo.getHouseholdId());
        record.setHouseholdRegisterNumber(citizenInfo.getHouseholdRegisterNumber());
        record.setHouseHoldTypeCode(citizenInfo.getHouseHoldTypeCode());
        record.setIdentNumber(citizenInfo.getIdentNumber());
        record.setIdentTypeCode(citizenInfo.getIdentTypeCode());
        record.setMaster(citizenInfo.getMaster());
        record.setName(citizenInfo.getName());
        record.setNameZw(citizenInfo.getNameZw());
        record.setNationCode(citizenInfo.getNationCode());
        record.setRelationCode(citizenInfo.getRelationCode());
        record.setTelephone(citizenInfo.getTelephone());*/

        entity.setRegisterId(null);
        entity.setCreateTime(DateUtil.getCurrentTime());

        registerSuccessMapperExt.insertSelective(entity);

        return entity;
    }

}
